<?php

namespace ticky;

use ticky\helper\url;

class request {

    /**
     * @var object 对象实例
     */
    protected static $instance;
    // 全局过滤规则
    protected $filter;
    // php://input
    protected $input;
    // 当前语言集
    protected $langset;

    /**
     * 构造函数
     * @access protected
     * @param array $options 参数
     */
    protected function __construct($options = array()) {
        foreach ($options as $name => $item) {
            if (property_exists($this, $name)) {
                $this->$name = $item;
            }
        }
        if (is_null($this->filter)) {
            $this->filter = config::get('app', 'default_filter');
        }

        // 保存 php://input
        $this->input = file_get_contents('php://input');
    }

    /**
     * 初始化
     * @access public
     * @param array $options 参数
     * @return \think\Request
     */
    public static function instance($options = []) {
        if (is_null(self::$instance)) {
            self::$instance = new static($options);
        }
        return self::$instance;
    }

    /**
     * 是否是GET请求
     * @return bool
     */
    public static function isGet() {
        return self::getMethod() === 'GET';
    }

    /**
     * 是否是POST请求
     * @return bool
     */
    public static function isPost() {
        return self::getMethod() === 'POST';
    }

    /**
     * 是否是OPTINS请求
     * @return bool
     */
    public static function isOptions() {
        return self::getMethod() === 'OPTIONS';
    }

    /**
     * 是否是HEAD请求
     * @return bool
     */
    public static function isHead() {
        return self::getMethod() === 'HEAD';
    }

    /**
     * 是否是DELETE请求
     * @return bool
     */
    public static function isDelete() {
        return self::getMethod() === 'DELETE';
    }

    /**
     * 是否是PUT请求
     * @return bool
     */
    public static function isPut() {
        return self::getMethod() === 'PUT';
    }

    /**
     * 是否是PATCH请求
     * @return bool
     */
    public static function isPatch() {
        return self::getMethod() === 'PATCH';
    }

    /**
     * 是否是TRACE请求
     * @return bool
     */
    public static function isTrace() {
        return self::getMethod() === 'TRACE';
    }

    /**
     * 是否是AJAX请求
     * @return bool
     */
    public static function isAjax() {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
    }

    /**
     * 是否是PAJX请求
     * @return bool
     */
    public static function isPjax() {
        return self::isAjax() && !empty($_SERVER['HTTP_X_PJAX']);
    }

    /**
     * 是否是FLASH请求
     * @return bool
     */
    public static function isFlash() {
        return isset($_SERVER['HTTP_USER_AGENT']) &&
                (stripos($_SERVER['HTTP_USER_AGENT'], 'Shockwave') !== false || stripos($_SERVER['HTTP_USER_AGENT'], 'Flash') !== false);
    }

    /**
     * 是否是命令行模式请求
     * @return bool
     */
    public static function isCLI() {
        return PHP_SAPI === 'cli';
    }

    /**
     * 是否是WINDOWS系统服务器发起请求
     * @return string
     */
    public static function isWin() {
        return strstr(PHP_OS, 'WIN');
    }

    /**
     * 是否是linux系统服务器发起请求
     * @return string
     */
    public static function isLinux() {
        return strstr(PHP_OS, 'Linux');
    }

    /**
     * 是否是微信发起请求
     * @return bool
     */
    public static function isWeChat() {
        return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false;
    }

    /**
     * 获取请求方法
     * @return string
     */
    public static function getMethod() {
        if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
            return strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
        }
        if (isset($_SERVER['REQUEST_METHOD'])) {
            return strtoupper($_SERVER['REQUEST_METHOD']);
        }
        return 'GET';
    }

    /**
     * 获取当前请求参数
     * @param $name
     * @param null $default
     * @return null
     */
    public static function getParam($name, $default = null) {

        // 判断是否是cli命令行模式
        if (self::isCLI()) {
            $params = array_filter($_SERVER['argv']);
            array_shift($params);
            foreach ($params as $k => $param) {
                if ($param[0] == '-' && $k % 2 == 0) {
                    $input[$params[$k][1]] = $params[$k + 1];
                }
            }
        } else {

            $method = strtoupper(self::getMethod());
            switch ($method) {
                case 'GET':
                    $input = $_GET;
                    break;
                case 'POST':
                    $input = $_POST;
                    break;
                default:
                    return null;
            }
        }
        if (!$name) {
            return $input;
        }
        $value = isset($input[$name]) ? $input[$name] : "";
        if (!isset($default)) {
            return $value;
        }
        // 强制类型转化
        gettype($default) == 'unknown type' or settype($value, gettype($default));
        return isset($value) ? $value : $default;
    }

    /**
     * 获取USER_AGENT
     * @return string
     */
    public static function getUA() {
        return isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : '';
    }

    public static function getUri() {
        return isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
    }

    /**
     * 获取当前请求的相对或绝对URL
     * @param bool $isAbsolute
     * @return null|string
     */
    public static function getUrl($isAbsolute = false) {
        $uri = self::getUri();
        if ($isAbsolute) {
            $protocol = self::getScheme() . '://';
            return $protocol . $_SERVER['HTTP_HOST'] . self::getUri();
        } else {
            return $uri;
        }
    }

    /**
     *  获取当前请求的协议类型
     */
    public static function getScheme() {
        return url::getScheme($_SERVER['SERVER_NAME']);
    }

    /**
     *  获取当前请求的HOST
     */
    public static function getHost() {
        return url::getHost(self::getUrl());
    }

    /**
     *  获取当前请求的域名
     */
    public static function getDomain() {
        return url::getDomain(self::getUrl());
    }

    /**
     * 获取当前请求的PATH
     * @return mixed
     */
    public static function getPath() {
        return url::getPath(self::getUrl());
    }

    /**
     * 获取当前请求的query字符串
     * @return mixed
     */
    public static function getQuery() {
        return url::getQuery(self::getUrl());
    }

    /**
     * 获取当前请求的URL扩展名
     * @return string
     */
    public static function getExtension() {
        return url::getExtension(self::getUrl(false));
    }

    /**
     * 获取当前请求的时间
     * @param bool $float
     * @return mixed
     */
    public static function getTime($float = false) {
        return $float ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME'];
    }

    /**
     *  获取服务端IP
     * @return string
     */
    public static function getServerIp() {
        if (isset($_SERVER)) {
            if ($_SERVER['SERVER_ADDR']) {
                $serverIp = $_SERVER['SERVER_ADDR'];
            } else {
                $serverIp = $_SERVER['LOCAL_ADDR'];
            }
        } else {
            $serverIp = getenv('SERVER_ADDR');
        }
        return filter_var($serverIp, FILTER_VALIDATE_IP) !== false ? $serverIp : '';
    }

    /**
     * 获取客户端IP
     * @return string
     */
    public static function getClientIp() {
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $clientIp = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $clientIp = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $clientIp = $_SERVER['REMOTE_ADDR'];
        } else {
            $clientIp = '0.0.0.0';
        }
        if ($clientIp == "::1") {
            return '0.0.0.0';
        } else {
            return filter_var($clientIp, FILTER_VALIDATE_IP) !== false ? $clientIp : '0.0.0.0';
        }
    }

    /**
     * 获取前一个页面
     * @return string
     */
    public static function getReffer() {
        return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
    }

    /**
     * 获取GET请求的值
     * @param $name
     * @param null $default
     * @return null
     */
    public static function get($name, $default = null) {
        // 判断是否是cli命令行模式
        if (self::isCLI()) {
            $params = array_filter($_SERVER['argv']);
            array_shift($params);
            foreach ($params as $k => $param) {
                if ($param[0] == '-' && $k % 2 == 0) {
                    $input[$params[$k][1]] = $params[$k + 1];
                }
            }
        } else {
            $input = $_GET;
        }
        if (!$name) {
            return $input;
        }
        if (isset($input[$name]) && $input[$name]) {
            $value = $input[$name];
        }
        if (!isset($default)) {
            return isset($value) ? $value : $default;
        }
        if (!isset($value)) {
            $value = $default;
        }
        // 强制类型转化
        gettype($default) == 'unknown type' or settype($value, gettype($default));
        return isset($value) ? $value : $default;
    }

    /**
     * 获取POST请求的值
     * @param $name
     * @param null $default
     * @return null
     */
    public static function post($name, $default = null) {
        $input = $_POST;
        if (!$name) {
            return $input;
        }
        if (isset($input[$name]) && $input[$name]) {
            $value = $input[$name];
        }
        if (!isset($default)) {
            return isset($value) ? $value : $default;
        }
        if (!isset($value)) {
            $value = $default;
        }
        // 强制类型转化
        gettype($default) == 'unknown type' or settype($value, gettype($default));
        return isset($value) ? $value : $default;
    }

    /**
     * 获取POST请求的值
     * @return array|void
     */
    public static function put() {
        $_PUT = array();
        if (self::getMethod() === "PUT") {
            parse_str(file_get_contents('php://input', false, null, -1, $_SERVER['CONTENT_LENGTH']), $_PUT);
        }
        return $_PUT;
    }

    /**
     * 获取上传的文件信息
     * @access public
     * @param string|array $name 名称
     * @return null|array|\think\File
     */
    public static function file($name = '') {
        $file = isset($_FILES) ? $_FILES : array();
        if (is_array($name)) {
            return $file = array_merge($file, $name);
        }
        $files = $file;
        if (!empty($files)) {
            // 处理上传文件
            $array = array();
            foreach ($files as $key => $file) {
                if (is_array($file['name'])) {
                    $item = [];
                    $keys = array_keys($file);
                    $count = count($file['name']);
                    for ($i = 0; $i < $count; $i++) {
                        if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) {
                            continue;
                        }
                        $temp['key'] = $key;
                        foreach ($keys as $_key) {
                            $temp[$_key] = $file[$_key][$i];
                        }
                        $item[] = (new upload($temp['tmp_name']))->setUploadInfo($temp);
                    }
                    $array[$key] = $item;
                } else {
                    if ($file instanceof File) {
                        $array[$key] = $file;
                    } else {
                        if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) {
                            continue;
                        }
                        $array[$key] = (new upload($file['tmp_name']))->setUploadInfo($file);
                    }
                }
            }
            if (strpos($name, '.')) {
                list($name, $sub) = explode('.', $name);
            }
            if ('' === $name) {
                // 获取全部文件
                return $array;
            } elseif (isset($sub) && isset($array[$name][$sub])) {
                return $array[$name][$sub];
            } elseif (isset($array[$name])) {
                return $array[$name];
            }

            /* debug($file);
              Array
              (
              [filename] => Array
              (
              [name] => ico-form-1.png
              [type] => image/png
              [tmp_name] => C:\Windows\temp\php87D7.tmp
              [error] => 0
              [size] => 5455
              )
              )
             */
        }
    }

}
